﻿// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.


using IdentityServer4.EntityFramework.DbContexts;
using IdentityServer4.EntityFramework.Mappers;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using IdentityServer4.EntityFramework.Storage;
using Serilog;
using Microsoft.AspNetCore.Identity;
using System.Collections.Generic;
using System.Security.Claims;
using Chen.IdentityServer4;
using IdentityModel;
using Microsoft.AspNetCore.Builder;

namespace Chen.IdentityServer4
{
    public class SeedData
    {
        public static void EnsureSeedData(string connectionString)
        {
            var services = new ServiceCollection();
            services.AddOperationalDbContext(options =>
            {
                options.ConfigureDbContext = db => db.UseMySql(connectionString, sql => sql.MigrationsAssembly(typeof(SeedData).Assembly.FullName));
            });
            services.AddConfigurationDbContext(options =>
            {
                options.ConfigureDbContext = db => db.UseMySql(connectionString, sql => sql.MigrationsAssembly(typeof(SeedData).Assembly.FullName));
            });

            var serviceProvider = services.BuildServiceProvider();

            using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                scope.ServiceProvider.GetService<PersistedGrantDbContext>().Database.Migrate();

                var context = scope.ServiceProvider.GetService<ConfigurationDbContext>();
                context.Database.Migrate();
                EnsureSeedData(context);

            }
        }

        public static void EnsureEmployeeDataAll(IApplicationBuilder app)
        {
            using(var scope = app.ApplicationServices.CreateScope())
            {
                var userContext = scope.ServiceProvider.GetService<ApplicationDbContext>();
                userContext.Database.Migrate();
                EnsureEmployeeData(userContext, scope);
            }
        }
        /// <summary>
        /// 初始化id4数据
        /// </summary>
        /// <param name="context"></param>
        private static void EnsureSeedData(ConfigurationDbContext context)
        {
            context.Clients.RemoveRange(context.Clients);
            context.ApiResources.RemoveRange(context.ApiResources);
            context.ApiScopes.RemoveRange(context.ApiScopes);
            context.SaveChanges();
            if (!context.Clients.Any())
            {
                Log.Debug("Clients being populated");
                foreach (var client in Config.Clients.ToList())
                {
                    context.Clients.Add(client.ToEntity());
                }
                context.SaveChanges();
            }
            else
            {
                Log.Debug("Clients already populated");
            }

            if (!context.IdentityResources.Any())
            {
                Log.Debug("IdentityResources being populated");
                foreach (var resource in Config.IdentityResources.ToList())
                {
                    context.IdentityResources.Add(resource.ToEntity());
                }
                context.SaveChanges();
            }
            else
            {
                Log.Debug("IdentityResources already populated");
            }

            if (!context.ApiScopes.Any())
            {
                Log.Debug("ApiScopes being populated");
                foreach (var resource in Config.ApiScopes.ToList())
                {
                    context.ApiScopes.Add(resource.ToEntity());
                }
                context.SaveChanges();
            }
            else
            {
                Log.Debug("ApiScopes already populated");
            }
            if (!context.ApiResources.Any())
            {
                Log.Debug("ApiResources being populated");
                foreach (var apiresource in Config.ApiResources.ToList())
                {
                    context.ApiResources.Add(apiresource.ToEntity());
                }
                context.SaveChanges();
            }
            else
            {
                Log.Debug("ApiResources already populated");
            }
        }
        /// <summary>
        /// 初始话用户数据
        /// </summary>
        /// <param name="context"></param>
        /// <param name="scope"></param>
        /// <exception cref="System.Exception"></exception>
        private static void EnsureEmployeeData(ApplicationDbContext context, IServiceScope scope)
        {
            var userManager = scope.ServiceProvider.GetService<UserManager<IdentityUser<int>>>();
            IdentityUser<int> user = new IdentityUser<int>()
            {
                UserName = "alice",
                Email = "1057295105@qq.com"
            };
            var u = userManager.FindByNameAsync(user.UserName).Result;
            if (u != null)
            {
                return;
            }
            var res = userManager.CreateAsync(user, "Cjj.123456").Result;
            if (!res.Succeeded)
            {
                throw new System.Exception("初始化用户数据失败");
            }
            var claims = new List<Claim>
            {
                new Claim(JwtClaimTypes.Name, user.UserName),
                new Claim(JwtClaimTypes.Email, user.Email),
                new Claim(JwtClaimTypes.GivenName, "CJJ"),
                new Claim(JwtClaimTypes.Email, "1057295105@QQ.COM"),
                new Claim(JwtClaimTypes.EmailVerified, "TRUE",ClaimValueTypes.Boolean),
                new Claim(JwtClaimTypes.WebSite, "https://dotnetchenjianjun.com")

            };
            res = userManager.AddClaimsAsync(user, claims).Result;
            if (!res.Succeeded)
            {
                throw new System.Exception("初始化用户Claim失败");
            }
        }



        ///原始的
        //private static void EnsureSeedData(ConfigurationDbContext context)
        //{
        //    if (!context.Clients.Any())
        //    {
        //        Log.Debug("Clients being populated");
        //        foreach (var client in Config.Clients.ToList())
        //        {
        //            context.Clients.Add(client.ToEntity());
        //        }
        //        context.SaveChanges();
        //    }
        //    else
        //    {
        //        Log.Debug("Clients already populated");
        //    }

        //    if (!context.IdentityResources.Any())
        //    {
        //        Log.Debug("IdentityResources being populated");
        //        foreach (var resource in Config.IdentityResources.ToList())
        //        {
        //            context.IdentityResources.Add(resource.ToEntity());
        //        }
        //        context.SaveChanges();
        //    }
        //    else
        //    {
        //        Log.Debug("IdentityResources already populated");
        //    }

        //    if (!context.ApiScopes.Any())
        //    {
        //        Log.Debug("ApiScopes being populated");
        //        foreach (var resource in Config.ApiScopes.ToList())
        //        {
        //            context.ApiScopes.Add(resource.ToEntity());
        //        }
        //        context.SaveChanges();
        //    }
        //    else
        //    {
        //        Log.Debug("ApiScopes already populated");
        //    }
        //}
    }
}
